define ['jquery'], ($) ->

	# Define a publish-subscribe mechanism based on jQuery events. We use a
	# closure to make the ps object private.
	( ->
		ps = $({})
		$.subscribe = ->
			ps.on.apply ps, arguments
			return
		$.unsubscribe = ->
			ps.off.apply ps, arguments
			return
		$.publish = ->
			ps.trigger.apply ps, arguments
			return
	)()


	# Define a jQuery method to label a custom plugin with a given
	# classname or to check if an object is a custom plugin.
	$.fn.pl_plugin = (x) ->
		if x then @addClass "pl_plugin #{x}" else @hasClass "pl_plugin"


	# Define a jQuery method to get a template from a DOM element and
	# return it as a text string.
	$.fn.template = ->
		tpl = @html()
		# Remove spaces between tags
		tpl = tpl?.replace(/>\s+</g, '><')
		# Remove leading and tra'.iling spaces
		tpl = tpl?.replace(/^\s+/g, '')?.replace(/\s+$/g, '')
		# Decode HTML entities in <%= and %> tags used by template
		tpl = tpl?.replace(/&lt;%=/g, '<%=')?.replace(/%&gt;/g, '%>')
		return tpl


	# Define a Sammy app helper to build content from a data object using a
	# template located in a jQuery object. It uses the Sammy.Template
	# plugin which supplies a Sammy event method called 'template()'.
	#
	# If data underspecifies the properties defined in template then
	# template() generates an Uncaught ReferenceError, but things are ok if
	# data overspecifies.

	# If 2nd param data is not given to template(), it does not return a
	# function as expected, because data is extended by the Sammy context.
	# However, if data is not extended then basic rendering does now work,
	# because some needed functions would be missing. Therefore, we cannot
	# code as follows.
	#tpl = S.template tpl
	#content = tpl data

	content = ($tpl, data) ->
		try
			@template $tpl.template(), data
		catch e
			if e instanceof ReferenceError
				console.log "#{e.name}: #{JSON.stringify e.arguments} #{e.type}"
			else
				throw e
			return null
